package com.lancoo.cvas.schedues;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReUtil;
import com.lancoo.cvas.config.LancooConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.sql.Date;
import java.time.LocalDate;

/**
 * @Author: liufeng
 * @CreateTime: 2024-03-27  09:22
 * @Description:
 */
@Component
@Slf4j
@EnableAsync(proxyTargetClass = true)
public class BackupDatabase {
    @Value("${spring.datasource.username}")
    private String user;
    @Value("${spring.datasource.password}")
    private String password;
    @Value("${spring.datasource.url}")
    private String url;

    @Resource
    private LancooConfig lancooConfig;

    @Scheduled(cron = "0 0 2 * * ?") //每天凌晨2点
    public void backupSchedule() throws IOException {
        log.info("系统开启定时任务数据库备份");
        // 动态截取数据库url中的数据库名称
        String regex = "jdbc:mysql://(.*):(\\d+)/(.*)\\?";
        String host = ReUtil.get(regex, url, 1);
        String port = ReUtil.get(regex, url, 2);
        String db = ReUtil.get(regex, url, 3);

        // 当前时间 年月日格式
        LocalDate localDate = LocalDate.now();
        // 备份文件名称
        String fileName = localDate.toString() + ".sql";
        String path = lancooConfig.getAppdataResource() + "/Soft_CVAS/backup/Database/" + Date.valueOf(LocalDate.now());
        // 输出
        File file = new File(path, fileName);
        file.getParentFile().mkdirs();
        file.createNewFile();
        // 备份今天数据库
        backup(file, user, password,host,port, db, lancooConfig.getMysqlPath());
        // 删除30天前数据库备份文件
        LocalDate before = localDate.minusDays(30);
        File backupDirectory = new File(path);
        File[] filesToDelete = backupDirectory.listFiles((dir, name) -> {
            if (name.endsWith(".sql")) {
                LocalDate fileDate = LocalDate.parse(name.substring(0, name.length() - 4)); // 解析文件名日期
                return fileDate.isBefore(before);
            }
            return false;
        });
        if (filesToDelete != null) {
            for (File delFile : filesToDelete) {
                boolean deleted = delFile.delete();
                if (deleted) {
                    log.info("成功删除文件: {}", delFile.getAbsolutePath());
                } else {
                    log.error("删除文件失败: {}", delFile.getAbsolutePath());
                }
            }
        }
    }


    public static void backup(File file, String user, String password,String host,String port, String db, String mysql_path) {
        try {
            Runtime rt = Runtime.getRuntime();
            String command = mysql_path + "/" + "mysqldump  " + "-u" + user + " -p" + password+ " -h" + host+ " -P" + port + "  " + db;
            Process child = rt.exec(command);

            InputStream inputStream = child.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
            String str;
            while ((str = bufferedReader.readLine()) != null) {
                outputStreamWriter.write(str + "\r\n");
            }
            outputStreamWriter.flush();
            inputStream.close();
            bufferedReader.close();
            outputStreamWriter.close();
            log.info("数据库备份成功:" + file.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
            log.error("数据库备份失败 : " + e.getMessage());
        }
    }


    /**
     * 定时删除数据库备份文件
     */
//    @Async
//    @Scheduled(cron = "0 0 0 * * ?")
    public void deleteBackUpDataBase() {
        log.info("======执行定时器:定时删除备份数据库文件=======");
        String backUpPath = lancooConfig.getAppdataResource() + "/Soft_CVAS/backup/Database";
        File backUpFile = new File(backUpPath);
        if (backUpFile.exists()) {
            File[] files = backUpFile.listFiles();
            for (File file : files) {
                if (file.isDirectory()) {
                    Date date1 = Date.valueOf(file.getName());
                    Date date2 = Date.valueOf(LocalDate.now());
                    long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
                    if (betweenDay > 30) {
                        File[] subFiles = file.listFiles();
                        for (File subFile : subFiles) {
                            subFile.delete();
                        }
                        file.delete();
                    }
                }
            }
        }
    }

}
